home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / 2KTETRIS.ZIP / TETRIS.ASM < prev    next >
Assembly Source File  |  1992-08-29  |  12KB  |  675 lines

  1. .MODEL TINY
  2.  
  3.     public  RandSeed
  4.     public    GetKey
  5.  
  6.     extrn   InitScreen:near
  7.     extrn     Bottom:near
  8.     extrn    PrintLong:near
  9.     extrn      Print:near
  10.     extrn    TestSpace:near
  11.     extrn    GameOverPrompt:near
  12.     extrn    PrintPause:near
  13.     extrn    RemovePause:near
  14.  
  15. LEVEL_WAIT_INIT    equ        700
  16. START_POS        equ        280
  17.  
  18. HISCORE_POS     equ        24
  19. SCORE_POS        equ        264
  20. LEVEL_POS        equ        424
  21.  
  22.  
  23. PREVIEW_POS        equ        380
  24.  
  25.  
  26. .CODE
  27. ORG 100h
  28.  
  29. Start   proc    near
  30.  
  31. ;     INITIALIZATION
  32. ;   **************
  33.  
  34.     cld
  35.  
  36. ;    Test command line
  37.     xor        bx,bx
  38.     xor        dl,dl
  39.     mov     cl,byte ptr ds:[80h]            ; Command line length
  40. cmd_loop:
  41.     and        cl,cl                            ;cl=0?
  42.     je        short cmd_loop_end
  43.     mov        al,byte ptr ds:[81h+bx]
  44.     dec        cl
  45.     inc        bx
  46.     cmp     al,' '                            ;skip space
  47.     jne     short not_space
  48.     cmp        dl,10
  49.     jne        short cmd_loop
  50.     xor        dl,dl
  51.     jmp        short cmd_loop
  52. not_space:
  53.     cmp        dl,0
  54.     je        short get_minus
  55.     push    ax
  56.     mov        ax,    word ptr StartLevel
  57.     mov        dl, 10
  58.     mul        dl
  59.     mov        word ptr StartLevel, ax
  60.     pop        ax
  61.     sub        al, byte ptr '0'
  62.     add        StartLevel,ax
  63.     jmp        short cmd_loop
  64. get_minus:
  65.     cmp        al,'-'
  66.     jne        cmd_error
  67.     and        cl,cl
  68.     je      cmd_error
  69.     mov        al,byte ptr ds:[81h+bx]
  70.     dec        cl
  71.     inc        bx
  72.     cmp        al,'p'                            ; preview mode
  73.     je        preview_mode
  74.     cmp        al,'l'
  75.     jne        cmd_error
  76.     inc        dx                                ; dx type boolean
  77.     jmp        short cmd_loop
  78. preview_mode:
  79.     inc        word ptr PreView
  80.     jmp        short cmd_loop
  81. cmd_loop_end:
  82.     cmp        word ptr StartLevel,0
  83.     je        short set_level
  84.     cmp     word ptr StartLevel,17
  85.     jbe        short level_ok
  86. cmd_error:
  87.     lea        dx, ErrorText
  88.     mov        ah,09h
  89.     int        21h
  90.     mov        ax,0h
  91.     int        21h
  92. set_level:
  93.     mov        word ptr StartLevel,1
  94. level_ok:
  95.  
  96. ;    Get old int 1ch
  97.     mov        ax,351ch                       ; Function 35 interrupt 1c
  98.     int     21h                             ; Get interrupt adress
  99.     mov     word ptr OldInt1c,bx           ; 1c clock tick
  100.     mov     ax,es
  101.     mov     word ptr OldInt1c+2,ax
  102.  
  103. ;    Store new int 1ch
  104.     mov     dx,offset _NewInt1c            ; Set clock tick
  105.     mov     ax,251ch                       ; to point to NewInt1c
  106.     int     21h
  107.  
  108. ;    Set ctrl/break int
  109.     mov        dx,offset quit
  110.     mov        al,23h
  111.     int        21h
  112.  
  113. ;    Play again starts here
  114. restart:
  115.     mov        ax,word ptr StartLevel
  116.     mov        word ptr Level,ax
  117.     mov        word ptr Score,0
  118.     mov        word ptr Score+2,0
  119.  
  120.     call    near ptr RandInit                  ; Initialize random numbers
  121.     call    near ptr InitScreen                   ; Initialize screen
  122.  
  123. ;    Print hiscore holder
  124.     mov        ah,02h
  125.     mov        dl,10
  126.     int        21h
  127.     mov        dl,13
  128.     int        21h
  129.     lea        dx, HiScoreName
  130.     mov        ah,09h
  131.     int        21h
  132.  
  133. ;    Print first preview
  134.     cmp        PreView,0
  135.     je        no_init_preview
  136.     mov        ax,OldRand
  137.     shl        ax,1
  138.     shl        ax,1
  139.     mov        PreItem,ax
  140.     mov        si,1
  141.     mov        di,PREVIEW_POS
  142.     call    Print
  143. no_init_preview:
  144.  
  145. ;    Calculate clicks before next level change
  146.     mov        ax, LEVEL_WAIT_INIT             ; wait level*700 clicks
  147.     mov        dx,    word ptr Level                ; befor next level change
  148.     mov        word ptr TimerInit,18
  149.     sub        word ptr TimerInit,dx
  150.     mul        dx
  151.     mov        word ptr LevelWait,ax           ; set LevelWait to 18-level
  152.  
  153. ;    Print out level
  154.     xor        dx,dx
  155.     mov        ax,word ptr Level               ; print level
  156.     mov        di,LEVEL_POS
  157.     call    PrintLong
  158.  
  159. ;    Print Hiscore
  160.     mov        dx, word ptr HiScore+2
  161.     mov        ax, word ptr Hiscore
  162.     mov        di, HISCORE_POS
  163.     call    PrintLong
  164.  
  165. ;    Main loop
  166. ;    *********
  167.  
  168.     jmp     short while_kbhit
  169. for_ever:
  170.     cmp     word ptr Timer,0
  171.     jne        short while_kbhit
  172.     mov        ax,word ptr TimerInit
  173.     mov        Timer,ax
  174.     call    near ptr Down                  ; go down
  175.     or        ax,ax
  176.     jne        while_kbhit
  177.     jmp        game_over
  178.  
  179. while_kbhit:
  180.     mov       ah,0bh
  181.     int       21h
  182.     or      al,al
  183.     je      short for_ever
  184.  
  185.     call    near ptr GetKey                      ; al=getkey
  186.  
  187.     cmp        al,'p'
  188.     jne        short not_p
  189.     xor        PreView,1
  190.     jnz        short prev_on
  191.     call    near ptr RemovePreView
  192.     jmp        not_p
  193. prev_on:
  194.     call     near ptr PrintPreView
  195. not_p:
  196.     or         al,al
  197.     je        zero_key
  198.     xor     ah,ah
  199.     sub        ax,'2'
  200.     mov        bx,ax
  201.     cmp        bx,7
  202.     ja        short while_kbhit
  203.     shl        bx,1
  204.     jmp        word ptr cs:jump_table2[bx]
  205. zero_key:
  206.  
  207.     call    near ptr GetKey                    ; al=getkey
  208.  
  209.    ;                    switch(ch)
  210.     cbw                                     ; ax=al
  211.     sub     ax,72
  212.     mov     bx,ax
  213.     cmp     bx,8
  214.     ja      short while_kbhit
  215.     shl     bx,1
  216.     jmp     word ptr cs:jump_table[bx]
  217. go_left:
  218.     push    si
  219.     mov        si,-2
  220.     call    Move
  221.     pop        si
  222.     jmp     short while_kbhit
  223. go_right:
  224.     push    si
  225.     mov        si,2
  226.     call    Move
  227.     pop        si
  228.     jmp     short while_kbhit
  229. go_drop:
  230.     call    Drop
  231.     or        ax,ax
  232.     je        short game_over
  233.     jmp     short while_kbhit
  234. go_rotate:
  235.     call    Rotate
  236.     jmp     short while_kbhit
  237. inc_level:
  238.     cmp        Level,17
  239.     jge        short while_kbhit
  240.     add        LevelWait,LEVEL_WAIT_INIT
  241.     inc        word ptr Level
  242.     dec        word ptr TimerInit
  243.     xor        dx,dx
  244.     mov        ax,word ptr Level
  245.     mov        di,LEVEL_POS
  246.     call    PrintLong
  247.     jmp     while_kbhit
  248. game_over:
  249.     mov        Timer,0
  250.     mov        Paused,1
  251.  
  252. ;    Test for new hiscore
  253.     mov        dx,word ptr Score+2
  254.     mov        ax,word ptr Score
  255.     cmp        word ptr HiScore+2,dx
  256.     ja        no_hiscore
  257.     jb        short new_hi
  258. test_lsw:
  259.     cmp        word ptr HiScore,ax
  260.     jb        short new_hi
  261.     jmp        short no_hiscore
  262. new_hi:
  263.     mov        word ptr HiScore,ax
  264.     mov        word ptr Hiscore+2,dx
  265.  
  266. ;    Get name of hiscore holder
  267.     lea        dx, EnterName
  268.     mov        ah,09h
  269.     int        21h
  270.     mov        dx, offset HiScoreData
  271.     mov        ah,0ah
  272.     int        21h
  273.     mov        bl,HiScoreData+1
  274.     inc        bl
  275.     xor        bh,bh
  276.     mov        HiscoreName[bx],13
  277.     inc        bl
  278.     mov        HiscoreName[bx],'$'
  279.  
  280.  
  281. ;    Get tetris filename
  282.     push    ds
  283.     mov     ah,30h
  284.     int     21h
  285.     mov     ax,ds:[002ch]
  286.     mov     es,ax
  287.     xor     di,di
  288.     mov     ax,di
  289.     mov     cx,07fffh
  290.     cld
  291. EnvLoop:
  292.     repnz scasb
  293.     cmp     es:[di],ah
  294.     jne     EnvLoop
  295.     or      ch,10000000b
  296.     neg     cx
  297.  
  298.     mov     si,cx
  299.     inc     si
  300.     inc     si
  301.  
  302.     push    ds
  303.     push    es
  304.     pop     ds
  305.     mov     dx,si
  306.     mov     ax,3d00h + 010b                 ; 010b = read/write
  307.     int     21h                                ; open tetris.com
  308.     pop        ds
  309.  
  310.     mov        bx,ax                            ; file handle
  311.     mov        ax,4200h                        ; lseek from start of file
  312.     mov        dx,offset HiscoreName
  313.     sub        dx,0100h
  314.     xor        cx,cx                            ; cx:dx=hiscorename
  315.     int        21h
  316.  
  317.     mov        ah,40h
  318.     mov        cx,offset OldInt1c-offset HiScoreName ; number of bytes to write
  319.     mov        dx,offset    HiScoreName
  320.     int        21h
  321.  
  322.     mov        ah,3eh                            ; close file
  323.     int        21h
  324.  
  325. no_hiscore:
  326.     call    near ptr GameOverPrompt
  327. yesno:
  328.     call    near ptr GetKey
  329.     cmp        al,'n'
  330.     je        quit
  331.     cmp        al,'y'
  332.     jne        yesno
  333. ;      Play again!
  334.     jmp restart
  335.  
  336. ;    Close down
  337. ;    **********
  338. quit:
  339.     mov     dx,word ptr OldInt1c                    ; restore old
  340.     mov     bx,word ptr OldInt1c+2                    ; interrupt 1c vector
  341.     push    ds
  342.     mov     ds,bx
  343.     mov     ax,251ch
  344.     int     21h
  345.     pop        ds
  346.  
  347.     mov        ax,0003h
  348.     int        10h
  349. ;    Enter dos
  350.     mov ax,0
  351.     int 21h
  352. Start   endp
  353.  
  354. jump_table      label   word
  355.     dw      go_rotate
  356.     dw      inc_level
  357.     dw      while_kbhit
  358.     dw      go_left
  359.     dw      while_kbhit
  360.     dw      go_right
  361.     dw      while_kbhit
  362.     dw      while_kbhit
  363.     dw      go_drop
  364. jump_table2        label word
  365.     dw        go_drop
  366.     dw        while_kbhit
  367.     dw        go_left
  368.     dw        go_rotate
  369.     dw        go_right
  370.     dw        while_kbhit
  371.     dw        inc_level
  372.  
  373. _NewInt1c       proc    far
  374.     push    ax
  375.     push    bx
  376.     push    cx
  377.     push    dx
  378.     push    di
  379.     push    si
  380.     push    bp
  381.     push    ds
  382.     push    es
  383.  
  384.     mov     bp,cs
  385.     mov     ds,bp
  386.     pushf
  387.     call    dword ptr OldInt1c
  388.  
  389.     inc        word ptr randseed
  390.     cmp        word ptr Timer,0
  391.     je        short pause
  392.     cmp        Paused,0
  393.     je        short pause_ok
  394.     call    RemovePause
  395.     mov        Paused,0
  396. pause_ok:
  397.     dec     word ptr Timer
  398.     dec        word ptr LevelWait
  399.     jne        short return
  400.     mov        word ptr LevelWait,LEVEL_WAIT_INIT
  401.     cmp        TimerInit,0
  402.     je        short return
  403.     dec        word ptr TimerInit
  404.     inc        word ptr Level
  405.     xor        dx,dx
  406.     mov        ax,word ptr Level
  407.     mov        di,LEVEL_POS
  408.     call    PrintLong
  409.     jmp        return
  410. pause:
  411.     cmp        Paused,0
  412.     jne        short return
  413.     call    PrintPause
  414.     mov        Paused,1
  415. return:
  416.     pop     es
  417.     pop     ds
  418.     pop     bp
  419.     pop     si
  420.     pop     di
  421.     pop     dx
  422.     pop     cx
  423.     pop     bx
  424.     pop     ax
  425.  
  426.     iret
  427. _NewInt1c       endp
  428.  
  429.  
  430.  
  431.  
  432. Move proc near                    ; si=dPos
  433.     push     si
  434.  
  435.     xor        si,si
  436.     mov        ax,word ptr Item
  437.     add        ax,word ptr Rotated
  438.     mov        di,word ptr Pos
  439.     call    near ptr Print                ; remove old
  440.  
  441.     mov        ax,word ptr Item
  442.     add        ax,word ptr Rotated
  443.     mov     di,word ptr Pos
  444.     pop     si
  445.     add        di,si
  446.     push     si
  447.     call    near ptr TestSpace                ; test if room
  448.     pop     si
  449.     push    ax
  450.     or        ax,ax
  451.     je        short no_room
  452.     add        word ptr Pos,si                ; ok, add Pos
  453. no_room:
  454.     push    si
  455.     mov     si,1
  456.     mov        ax,word ptr Item
  457.     add        ax,word ptr Rotated
  458.     mov        di,word ptr Pos
  459.     call    near ptr Print
  460.     pop        si
  461.     pop        ax
  462.     ret
  463. Move endp
  464.  
  465. Rotate    proc    near
  466.     push si
  467.     xor     si,si
  468.     mov        ax,word ptr Item
  469.     add        ax,word ptr Rotated
  470.     mov        di,word ptr Pos
  471.     call    near ptr Print
  472.  
  473.     mov        ax,word ptr Rotated
  474.     inc        ax
  475.     mov        bx,4
  476.     cwd
  477.     idiv    bx
  478.     mov        ax,word ptr Item
  479.     add        ax,dx
  480.     mov        di,word ptr Pos
  481.     call    near ptr TestSpace
  482.     or        ax,ax
  483.     je        short no_room1
  484.     mov        ax,word ptr Rotated
  485.     inc        ax
  486.     mov        bx,4
  487.     cwd
  488.     idiv    bx
  489.     mov        word ptr Rotated,dx
  490. no_room1:
  491.  
  492.     mov        si,1
  493.     mov        ax,word ptr Item
  494.     add        ax,word ptr Rotated
  495.     mov        di,Pos
  496.     call    near ptr Print
  497.     pop        si
  498.     ret
  499. Rotate    endp
  500.  
  501. Down    proc    near
  502.     push     si
  503.     mov     si,80
  504.     call    Move
  505.  
  506.     or        ax,ax                        ; room?
  507.     je        get_new                            ; no
  508.     pop        si
  509.     ret
  510. get_new:
  511.     mov        ax,word ptr Item
  512.     add        ax,word ptr Rotated
  513.     mov        di,word ptr Pos
  514.     call    near ptr Bottom            ; reached the bottom
  515.  
  516.     call    near ptr Rand7            ; get new item
  517.     shl        ax,1
  518.     shl        ax,1
  519.     mov        word ptr Item,ax
  520.     mov        word ptr Pos,START_POS
  521.     mov        word ptr Rotated,0
  522.  
  523. ;    Calculate score
  524.     mov        ax,word ptr Drops
  525.     shr        ax,1
  526.     add        ax,2
  527.     sub        ax,PreView
  528.     mov        dx,word ptr Level
  529.     mul        dx
  530.     add        Score,ax
  531.     adc        Score+2,dx
  532.     mov        di,SCORE_POS
  533.     mov        ax,Score
  534.     mov        dx,Score+2
  535.     call    PrintLong
  536.     mov        word ptr Drops,0
  537.  
  538. ;    Test if new tetris can be printed
  539.     mov        ax,word ptr Item
  540.     add        ax,word ptr Rotated
  541.     mov        di,Pos
  542.     call    TestSpace
  543.     or        ax,ax
  544.     jne        place_new
  545.  
  546. ;    There was no room. Return false!
  547.     pop        si
  548.     ret
  549.  
  550. ;     There was room. Print tetris.
  551. place_new:
  552.     mov        si,1
  553.     mov        ax,word ptr Item
  554.     add        ax,word ptr Rotated
  555.     mov        di,Pos
  556.     call    Print
  557.     mov        ax,    word ptr TimerInit
  558.     mov        word ptr Timer,ax
  559.  
  560. ;    Display preview tetris
  561.     cmp        PreView,0
  562.     je        short no_preview
  563.     call    near ptr RemovePreView
  564.     call    near ptr PrintPreview
  565. ;    Return true.
  566. no_preview:
  567.     mov     ax,1
  568.     pop     si
  569.     ret
  570. Down    endp
  571.  
  572. Drop    proc    near
  573.     push    si
  574.     mov        si,80
  575. drop_more:
  576.     call    Move
  577.     inc        word ptr Drops
  578.     or        ax,ax
  579.     jne        drop_more
  580.  
  581.     call    near ptr Down
  582.     pop        si
  583.     ret
  584. Drop    endp
  585.  
  586. PrintPreView    proc near
  587.     mov        si,1
  588.     mov        ax,OldRand
  589.     shl        ax,1
  590.     shl        ax,1
  591.     mov        PreItem,ax
  592.     mov        di,PREVIEW_POS
  593.     call    Print
  594.     ret
  595. PrintPreView    endp
  596.  
  597. RemovePreView    proc near
  598.     xor     si,si
  599.     mov        ax,word ptr PreItem
  600.     mov        di,PREVIEW_POS
  601.     call    Print
  602.     ret
  603. RemovePreView    endp
  604.  
  605.  
  606. GetKey proc    near
  607.     mov      ah,07h
  608.     mov      dl,0ffh
  609.     int      21h
  610.     ret
  611. GetKey endp
  612.  
  613. RandInit       proc    near
  614.     mov     bp,sp
  615.     sub     sp,4
  616.     mov      ah,02h
  617.     int      1ah
  618.     mov      [bp-2],cl
  619.     mov      [bp-4],dh
  620.     mov     ax,word ptr [bp-2]
  621.     imul    word ptr [bp-4]
  622.     mov     word ptr randseed,ax
  623.     mov     sp,bp
  624.     call    near ptr Rand7
  625.     ret
  626. RandInit       endp
  627.  
  628. Rand7  proc    near
  629.     mov     ax,word ptr randseed
  630.     imul    word ptr randseed
  631.  
  632.     test    ax,1
  633.     je      short even_number
  634.     add     ax,3172
  635.     mov     word ptr randseed,ax
  636.     jmp     short skip_even
  637. even_number:
  638.     shl        ax,1
  639.     add        ax,Score
  640. skip_even:
  641.     mov     word ptr randseed,ax
  642.     mov     bx,7
  643.     xor     dx,dx
  644.     div     bx
  645.     mov     ax, word ptr OldRand
  646.     mov        word ptr OldRand, dx
  647.     ret
  648. Rand7  endp
  649.  
  650. .DATA
  651. Timer         dw     0
  652. LevelWait   dw    LEVEL_WAIT_INIT
  653. Level        dw    1
  654. StartLevel    dw    0
  655. Pos            dw    START_POS
  656. Item        dw    0
  657. Rotated        dw    0
  658. Drops        dw  0
  659. RandSeed    dw    0
  660. PreView        dw    0
  661. Paused      db  0
  662. ErrorText    db    'Bad arguments',10,'$'
  663. EnterName    db    'Enter name:',10,13,'$'
  664. HiScoreData db    14,0
  665. HiScoreName db    15 dup ('$')
  666. HiScore     dd    0
  667. OldInt1c     db  4 dup (?)
  668. Score        dw    2 dup (?)
  669. OldRand        dw    1 dup (?)
  670. PreItem        dw    1 dup (?)
  671. TimerInit    dw    1 dup (?)
  672.  
  673. end Start
  674.  
  675.